package com.atom.wyz.new_opengl.util;

import android.content.res.Resources;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

public class LoadUtil {
    // 获取叉积 也就是预期垂直的
    public static float[] getCrossProduct(float x1, float y1, float z1, float x2, float y2, float z2) {
        float A = y1 * z2 - y2 * z1;
        float B = z1 * x2 - z2 * x1;
        float C = x1 * y2 - x2 * y1;
        return new float[]{A, B, C};
    }
    // 获取规格化的向量,长度为1
    public static float[] vectorNormal(float[] vector) {
        float module = (float) Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]);
        return new float[]{vector[0] / module, vector[1] / module, vector[2] / module}; //返回􏰨􏰩化的向量
    }
    public interface CreateObjectLoader {
        void create(Resources resources , float[] vertexArray, float[] normalArray, float[] texcoorsArray);
    }

    public static void getLoadObj(Resources resources , String objPath, @NonNull CreateObjectLoader createLoaderFunction) {
        boolean normalHasData = false;
        boolean texcoorsHasData = false;
        ArrayList<Float> vertexListTemp = new ArrayList<>();
        ArrayList<Float> vertexListResult = new ArrayList<>();

        ArrayList<Float> normalListTemp = new ArrayList<Float>();
        ArrayList<Float> normalListResult = new ArrayList<Float>();

        ArrayList<Float> texcoorsListTemp = new ArrayList<Float>();
        ArrayList<Float> texcoorslListResult = new ArrayList<Float>();

        ArrayList<Integer> alFaceIndex = new ArrayList<Integer>();//结果顶点􏳫􏳬􏳤􏳥
        HashMap<Integer, HashSet<Normal>> hmn = new HashMap<Integer, HashSet<Normal>>();
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            inputStream = resources.getAssets().open(objPath);
            inputStreamReader = new InputStreamReader(inputStream);
            bufferedReader = new BufferedReader(inputStreamReader);
            String tempStr = null;
            Log.e("LoadUtil", "start while to read ");
            while ((tempStr = bufferedReader.readLine()) != null) {
                String[] tempsa = tempStr.split("[ ]+");
                switch (tempsa[0].trim()) {
                    case "v": {
                        vertexListTemp.add(Float.parseFloat(tempsa[1]));//将顶点的 x、y、z 坐标存入
                        vertexListTemp.add(Float.parseFloat(tempsa[2]));//原始顶点坐标􏰰􏰱
                        vertexListTemp.add(Float.parseFloat(tempsa[3]));
                        break;
                    }
                    case "vt": {
                        texcoorsListTemp.add(Float.parseFloat(tempsa[1]));
                        texcoorsListTemp.add(1 - Float.parseFloat(tempsa[2]));
                        break;
                    }
                    case "vn": {
                        normalListTemp.add(Float.parseFloat(tempsa[1]));
                        normalListTemp.add(Float.parseFloat(tempsa[2]));
                        normalListTemp.add(Float.parseFloat(tempsa[3]));
                        break;
                    }
                    case "f": {

                        /**f 1/1/1 2/2/2 3/3/3
                         *  1/1/1  第一个点的 顶点索引/纹理索引/法线索引
                         *  tempsa[1].split("/")[0] > 找到第一个顶点的索引 -1 代表在集合中从0开始
                         */
                        Integer[] index = new Integer[3];
                        String[] split = tempsa[1].split("\\/");

                        index[0] = Integer.parseInt(split[0]) - 1;
                        int indexT = 0;

                        if (split.length >= 2 || texcoorsHasData) {
                            indexT = Integer.parseInt(split[1]) - 1;
                            if (!texcoorsHasData) texcoorsHasData = true;
                        }
                        int indexN = 0;
                        if (split.length >= 3 || normalHasData) {
                            indexN = Integer.parseInt(split[2]) - 1;
                            if (!normalHasData) normalHasData = true;
                        }

                        //三角形第一个点的 x  y  z

                        float x1 = vertexListTemp.get(3 * index[0]);
                        float y1 = vertexListTemp.get(3 * index[0] + 1);
                        float z1 = vertexListTemp.get(3 * index[0] + 2);
                        vertexListResult.add(x1);
                        vertexListResult.add(y1);
                        vertexListResult.add(z1);


                        if (texcoorsHasData) {
                            texcoorslListResult.add(texcoorsListTemp.get(2 * indexT));
                            texcoorslListResult.add(texcoorsListTemp.get(2 * indexT + 1));

                        }
                        if (normalHasData) {
                            normalListResult.add(normalListTemp.get(3 * indexN));
                            normalListResult.add(normalListTemp.get(3 * indexN + 1));
                            normalListResult.add(normalListTemp.get(3 * indexN + 2));
                        }


                        //tempsa[2].split("/")[0] 代表第二个顶点的索引
                        split = tempsa[2].split("\\/");
                        index[1] = Integer.parseInt(split[0]) - 1;
                        if (texcoorsHasData) {
                            indexT = Integer.parseInt(split[1]) - 1;
                        }
                        if (normalHasData) {
                            indexN = Integer.parseInt(split[2]) - 1;
                        }
                        float x2 = vertexListTemp.get(3 * index[1]);
                        float y2 = vertexListTemp.get(3 * index[1] + 1);
                        float z2 = vertexListTemp.get(3 * index[1] + 2);
                        vertexListResult.add(x2);
                        vertexListResult.add(y2);
                        vertexListResult.add(z2);


                        if (texcoorsHasData) {
                            texcoorslListResult.add(texcoorsListTemp.get(2 * indexT));
                            texcoorslListResult.add(texcoorsListTemp.get(2 * indexT + 1));
                        }
                        if (normalHasData) {
                            normalListResult.add(normalListTemp.get(3 * indexN));
                            normalListResult.add(normalListTemp.get(3 * indexN + 1));
                            normalListResult.add(normalListTemp.get(3 * indexN + 2));
                        }

                        split = tempsa[3].split("\\/");
                        index[2] = Integer.parseInt(split[0]) - 1;
                        if (texcoorsHasData) {
                            indexT = Integer.parseInt(split[1]) - 1;
                        }
                        if (normalHasData) {
                            indexN = Integer.parseInt(split[2]) - 1;
                        }
                        float x3 = vertexListTemp.get(3 * index[2]);
                        float y3 = vertexListTemp.get(3 * index[2] + 1);
                        float z3 = vertexListTemp.get(3 * index[2] + 2);
                        vertexListResult.add(x3);
                        vertexListResult.add(y3);
                        vertexListResult.add(z3);

                        if (texcoorsHasData) {
                            texcoorslListResult.add(texcoorsListTemp.get(2 * indexT));
                            texcoorslListResult.add(texcoorsListTemp.get(2 * indexT + 1));
                        }
                        if (normalHasData) {
                            normalListResult.add(normalListTemp.get(3 * indexN));
                            normalListResult.add(normalListTemp.get(3 * indexN + 1));
                            normalListResult.add(normalListTemp.get(3 * indexN + 2));
                        }

                        alFaceIndex.add(index[0]);
                        alFaceIndex.add(index[1]);
                        alFaceIndex.add(index[2]);

                        //􏰥三角形中第一个点到第二个点的向量
                        float vxa = x1 - x2;
                        float vya = y1 - y2;
                        float vza = z1 - z2;
                        //􏰥三角形中第一个点到第三个点的向量
                        float vxb = x1 - x3;
                        float vyb = y1 - y3;
                        float vzb = z1 - z3;
                        float[] normal = vectorNormal(getCrossProduct(vxa, vya, vza, vxb, vyb, vzb));

                        for (Integer tempInxex : index) {
                            HashSet<Normal> hsn = hmn.get(tempInxex); //获取指定􏳫􏳬顶点的法向量􏴂合
                            if (hsn == null) {
                                hsn = new HashSet<>();
                            }
                            hsn.add(new Normal(normal[0], normal[1], normal[2]));
                            hmn.put(tempInxex, hsn);
                        }
                        break;
                    }

                }
            }
            //顶点数据格式化
            int size = vertexListResult.size();
            float[] vertexArray = new float[vertexListResult.size()];
            for (int i = 0; i < size; i++) {
                vertexArray[i] = vertexListResult.get(i);
            }
            Log.e("LoadUtil", "create normalArray ");
            //法线数据格式化 自己计算的

            float[] normalArray = null;
            if (normalListResult.size() > 0) {
                normalArray = new float[normalListResult.size()];
                for (int i = 0; i < normalArray.length; i++) {
                    normalArray[i] = normalListResult.get(i);
                }
            } else {
                normalArray = new float[vertexListResult.size()];
                int c = 0;
                for (Integer item : alFaceIndex
                ) {
                    HashSet<Normal> hsn = hmn.get(item);
                    if (hsn == null) continue;
                    float[] tn = Normal.getAverage(hsn);
                    normalArray[c++] = tn[0];
                    normalArray[c++] = tn[1];
                    normalArray[c++] = tn[2];
                }
            }
            Log.e("LoadUtil", "create texcoorsArray ");
            //纹理数据格式化
            float[] texcoorsArray = null;
            if (texcoorslListResult.size() > 0) {
                texcoorsArray = new float[texcoorslListResult.size()];
                for (int i = 0; i < texcoorsArray.length; i++) {
                    texcoorsArray[i] = texcoorslListResult.get(i);
                }
            }
            createLoaderFunction.create(resources, vertexArray, normalArray, texcoorsArray);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        inputStreamReader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }


}
